#!/usr/bin/env python

import wx
import os
import sys
import re
import popen2
import about

class MrMTGuiMain(wx.Frame):
    mtfiletype = 'Executable |*.*'
    paupfiletype = 'PAUP executable | *.*'
    nexusfiletype = 'Nexus files | *.nex'
    frombutton = True
    fromMT = True

    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id,  'ModelPie', size=(650, 430), style=wx.DEFAULT_FRAME_STYLE ^ 
(wx.RESIZE_BORDER | wx.MAXIMIZE_BOX))
        self.__do_layout()
        self.__do_binding()

    def __do_layout(self):
        currentdir = os.getcwd()
        self.panel = wx.Panel(self)
        
        '''icon'''
        self.SetIcon(wx.Icon(currentdir + "/images/modelpie.png", wx.BITMAP_TYPE_PNG))
        
        '''menu'''
        menubar = wx.MenuBar()
        aboutmenu = wx.Menu()
        about = aboutmenu.Append(-1, 'About ModelPie', '')
        help = aboutmenu.Append(-1, 'Help', '')
        aboutmenu.AppendSeparator()
        quit = aboutmenu.Append(-1, 'Quit', '')
        menubar.Append(aboutmenu, '?')
        self.SetMenuBar(menubar)
        self.Bind(wx.EVT_MENU, self.OnMenuAbout, about)
        self.Bind(wx.EVT_MENU, self.OnMenuHelp, help)
        self.Bind(wx.EVT_MENU, self.OnMenuQuit, quit)
        
        '''MT side'''
        self.label1 = wx.StaticText(self.panel, label='ModelTest:', pos=(10,10))
        self.paupButton = wx.Button(self.panel, label='Run PAUP', pos=(15, 30), size=(110,27))
        self.paramButton = wx.Button(self.panel, label='Parameters', pos=(15,60), size=(110,27))
        self.paramButton.Enable(False) #disabled for now
        self.runMTButton= wx.Button(self.panel, label='ModelTest !!!', pos=(15, 90), size=(110,27))
        self.bicCheck = wx.CheckBox(self.panel, label='Use BIC', pos=(15,120), size=(110,27))
        self.editMTButton = wx.Button(self.panel, label='Edit Nexus', pos=(15,150), size=(110,27))
        self.saveMTButton = wx.Button(self.panel, label='Save scores', pos=(15,180), size=(110,27))

        if paths[0] == 0:
            self.runMTButton.Enable(False)
            self.paupButton.Enable(False)
            #self.selMTFileButton.Enable(False)

        self.editMTButton.Enable(False)
        self.saveMTButton.Enable(False)

        '''MrMT side'''
        self.label2 = wx.StaticText(self.panel, label='MrModelTest:', pos=(510,10))
        self.paupButton2 = wx.Button(self.panel, label='Run PAUP', pos=(515, 30), size=(110,27))
        self.runMrButton = wx.Button(self.panel, label='MrModelTest!!!', pos=(515, 60), size=(110,27))
        self.editMrButton = wx.Button(self.panel, label='Edit Nexus', pos=(515, 150), size=(110,27))
        self.saveMrButton = wx.Button(self.panel, label='Save scores', pos=(515, 180), size=(110,27))

        if paths[1] == 0:
            self.runMrButton.Enable(False)
            self.paupButton2.Enable(False)
            #self.selMrFileButton.Enable(False)

        self.editMrButton.Enable(False)
        self.saveMrButton.Enable(False)

        if paths[2] == 0:
            self.paupButton.Enable(False)
            self.paupButton2.Enable(False)

        '''Center'''
        style = (wx.TE_MULTILINE | wx.TE_READONLY |wx.TE_RICH2 | wx.TE_DONTWRAP)
        self.resultText = wx.TextCtrl(self.panel, pos=(150, 30), size=(350,300), style=style)
        self.MTButton = wx.Button(self.panel, label='MT Path', pos=(150, 350), size=(110,28))
        self.paupPathButton = wx.Button(self.panel, label = 'Paup Path', pos=(270, 350), size=(110,28))
        self.MrMTButton = wx.Button(self.panel, label = 'MrMT Path', pos=(390, 350), size=(110,28))
        self.pathButton = wx.Button(self.panel, label = 'Check Paths', pos=(510, 350), size=(110,28))
        self.resultText.SetFont(wx.Font(8, wx.MODERN, wx.NORMAL, wx.NORMAL))
        self.resultText.write('Your results will be displayed here')

    def __do_binding(self):
        self.Bind(wx.EVT_BUTTON, self.OnPaupPath, self.paupPathButton)
        self.Bind(wx.EVT_BUTTON, self.OnMTPath, self.MTButton)
        self.Bind(wx.EVT_BUTTON, self.OnMrPath, self.MrMTButton)

        self.Bind(wx.EVT_BUTTON, self.OnRunPaupMT, self.paupButton)
        self.Bind(wx.EVT_BUTTON, self.OnModelTest, self.runMTButton)
        self.Bind(wx.EVT_BUTTON, self.OnSaveMT, self.saveMTButton)
        self.Bind(wx.EVT_BUTTON, self.OnEditNexus, self.editMTButton)
        
        self.Bind(wx.EVT_BUTTON, self.OnRunPaupMr, self.paupButton2)
        self.Bind(wx.EVT_BUTTON, self.OnMrModelTest, self.runMrButton)
        self.Bind(wx.EVT_BUTTON, self.OnSaveMr, self.saveMrButton)
        self.Bind(wx.EVT_BUTTON, self.OnEditNexus, self.editMrButton)
        
        self.Bind(wx.EVT_BUTTON, self.OnCheckPaths, self.pathButton)

    def OnMrPath(self, event):
        dialog = wx.FileDialog(self, 'Set MrModelTest Path ...', os.getcwd(), style=wx.OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            mrpath = dialog.GetPath()
            dialog.Destroy()
            inifile = open(sys.path[0] + '/.mr.ini', 'w')
            inifile.write(mrpath)
            inifile.close()
            if len(paths) > 0:
                paths[1] = mrpath
            self.MrMTButton.Enable(True)

    def OnMTPath(self, event):
        dialog = wx.FileDialog(self, 'Set ModelTest Path ...', os.getcwd(), style=wx.OPEN, wildcard=self.mtfiletype)
        if dialog.ShowModal() == wx.ID_OK:
            mtpath = dialog.GetPath()
            dialog.Destroy()
            inifile = open(sys.path[0] + '/.mt.ini', 'w')
            inifile.write(mtpath)
            inifile.close()
            if len(paths) > 0:
                paths[0] = mtpath
            self.MTButton.Enable(True)

    def OnPaupPath(self, event):
        dialog = wx.FileDialog(self, 'Set PAUP Path ...', os.getcwd(), style=wx.OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            pauppath = dialog.GetPath()
            dialog.Destroy()
            inifile = open(sys.path[0] + '/.p.ini', 'w')
            inifile.write(pauppath)
            inifile.close()
            if len(paths) > 0:
                paths[2] = pauppath
            self.paupButton2.Enable(True)
            self.paupButton.Enable(True)
        
    def OnCheckPaths(self, event):
        self.resultText.Clear()
        for i in paths:
            self.resultText.write(i + '\n')
            
    def OnRunPaupMT(self, event):
        mtblock = open(sys.path[0] + '/block.dat', 'r').readlines()
        dialog = wx.FileDialog(self, 'Select Nexus file', os.getcwd(), style=wx.OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            try:
                os.remove(sys.path[0] + '/model.scores')
            except:
                print 'none'
            nexusfile = dialog.GetPath()
            dialog.Destroy()
            isnexus = self.check_nexus(nexusfile)
            if isnexus == 1:
                tempblock = mtblock
                tempblock.insert(2, 'BEGIN PAUP;\n')
                tempblock.insert(3, 'execute \'' + nexusfile + '\';\nlog file=\'' + nexusfile + '.log\' replace; \n')
                tempblock.insert(4, 'END;\n')
                tempblock.insert(272, 'quit warntsave=no;\n')
                runfile = open('paupfile.txt', 'w')
                for line in tempblock:
                    runfile.write(line)
                runfile.close()
                buffer = os.popen(paths[2] + ' ' + 'paupfile.txt', 'r')
                count = 0
                progressdialog = wx.ProgressDialog("PAUP run","Running PAUP - Model", 57, style= wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
                while count < 56:
                    line = buffer.readline()
                    if line.find('Likelihood scores') >= 0:
                        count += 1
                        updatedlg = progressdialog.Update(count, 'Running PAUP - Model ' + str(count))
                progressdialog.Destroy()
                mtdlg = wx.MessageDialog(None, "Do you want to run ModelTest?\nClick yes to proceed",'Run ModelTest?', wx.YES_NO | wx.ICON_QUESTION)
                userchoice = mtdlg.ShowModal()
                runfile.close()
                nexusfile = ''
                if (userchoice == wx.ID_YES):
                    self.frombutton = False
                    self.OnModelTest(wx.EVT_BUTTON)
                else:
                    wx.MessageBox('The PAUP result is inside ModelPie directory ' + sys.path[0])
            else:
                wx.MessageBox('Not a Nexus file\nPlease select another file')

    def OnRunPaupMr(self, event):
        mrblock = open(sys.path[0] + '/mrblock.dat', 'r').readlines()
        dialog = wx.FileDialog(self, 'Select Nexus file', os.getcwd(), style=wx.OPEN)
        if dialog.ShowModal() == wx.ID_OK:
            try:
                os.remove(sys.path[0] + '/mrmodel.scores')
            except:
                print 'none'
            nexusfile = dialog.GetPath()
            dialog.Destroy()
            isnexus = self.check_nexus(nexusfile)
            if isnexus == 1:
                tempblock = mrblock
                tempblock.insert(2, 'BEGIN PAUP;\n')
                tempblock.insert(3, 'execute ' + nexusfile + ';\nlog file=\'' + nexusfile + '.log\' replace; \n')
                tempblock.insert(4, 'END;\n')
                tempblock.insert(121, 'quit warntsave=no;\n')
                runfile = open('paupfile.txt', 'w')
                for line in tempblock:
                    runfile.write(line)
                runfile.close()
                buffer = os.popen(paths[2] + ' ' + 'paupfile.txt', 'r')
                count = 0
                progressdialog = wx.ProgressDialog("PAUP run","Running PAUP - Model", 25, style= wx.PD_ELAPSED_TIME | wx.PD_REMAINING_TIME)
                while count < 24:
                    line = buffer.readline()
                    if line.find('Likelihood scores') >= 0:
                        count += 1
                        updatedlg = progressdialog.Update(count, 'Running PAUP - Model ' + str(count))
                
                progressdialog.Destroy()
                mtdlg = wx.MessageDialog(None, "Do you want to run MrModelTest?\nClick yes to proceed",'Run MrModelTest?', wx.YES_NO | wx.ICON_QUESTION)
                userchoice = mtdlg.ShowModal()
                runfile.close()
                if (userchoice == wx.ID_YES):
                    self.frombutton = False
                    self.OnMrModelTest(wx.EVT_BUTTON)
                else:
                    wx.MessageBox('The PAUP result is inside ModelPie directory ' + sys.path[0])
            else:
                wx.MessageBox('Not a Nexus file\nPlease select another file')

    def OnModelTest(self, event):
        self.fromMT = True
        try:
            os.remove(sys.path[0] + '/mtresult')
        except:
            print 'none'        
        if self.frombutton == False:
            print paths[0] + ' < ' + sys.path[0] + '/model.scores > mtresult'
            if self.bicCheck.GetValue() == True:
                samplesize = wx.GetTextFromUser('Please enter the sample size', caption="Please enter the sample size:", default_value="", parent=None)
                if samplesize.isdigit() == True:
                    buffer = os.popen(paths[0] + ' -b -n' + samplesize + ' < ' + sys.path[0] + '/model.scores > mtresult', 'r')
                else:
                    wx.MessageBox('Run aborted. Invalid value supplied.\nPlease try again')
            else:
                buffer = os.popen(paths[0] + ' < ' + sys.path[0] + '/model.scores > mtresult', 'r')
            temp = buffer.readline()
            if not temp:        
                result = open(sys.path[0] + '/mtresult', 'r').readlines()
                self.resultText.Clear()
                for line in result:
                    self.resultText.write(line)
                self.resultText.SetInsertionPoint(0)
            self.editMTButton.Enable(True)
            self.saveMTButton.Enable(True)
        else:
            seldlg = wx.FileDialog(self, 'Select scores file', os.getcwd(), style=wx.OPEN)
            if seldlg.ShowModal() == wx.ID_OK:
                scorefile = seldlg.GetPath()
                seldlg.Destroy()
                if self.bicCheck.GetValue() == True:
                    samplesize = wx.GetTextFromUser('Please enter the sample size', caption="Please enter the sample size:", default_value="", parent=None)
                    if samplesize.isdigit() == True:
                        buffer = os.popen(paths[0] + ' -b -n' + samplesize + ' < ' + sys.path[0] + '/model.scores > mtresult', 'r')
                    else:
                         wx.MessageBox('Run aborted. Invalid value supplied.\nPlease try again')
                else:
                    buffer = os.popen(paths[0] + ' < ' + sys.path[0] + '/model.scores > mtresult', 'r')
                temp = buffer.readline()
                if not temp:        
                    result = open(sys.path[0] + '/mtresult', 'r').readlines()
                    self.resultText.Clear()
                    for line in result:
                        self.resultText.write(line)
                    self.resultText.SetInsertionPoint(0)
                self.editMTButton.Enable(True)
                self.saveMTButton.Enable(True)
        self.frombutton = True

    def OnMrModelTest(self, event):
        self.fromMT = False
        try:
            os.remove(sys.path[0] + '/mresult')
        except:
            print 'none'
        if self.frombutton == False:
            buffer = os.popen(paths[0] + ' < ' + sys.path[0] + '/model.scores > mresult', 'r')
            temp = buffer.readline()
            if not temp:        
                result = open(sys.path[0] + '/mresult', 'r').readlines()
                self.resultText.Clear()
                for line in result:
                    self.resultText.write(line)
                self.resultText.SetInsertionPoint(0)
            self.editMrButton.Enable(True)
            self.saveMrButton.Enable(True)
        else:
            seldlg = wx.FileDialog(self, 'Select scores file', os.getcwd(), style=wx.OPEN)
            if seldlg.ShowModal() == wx.ID_OK:
                scorefile = seldlg.GetPath()
                seldlg.Destroy()
                buffer = os.popen(paths[0] + ' < ' + sys.path[0] + '/model.scores > mresult', 'r')
                temp = buffer.readline()
                if not temp:        
                    result = open(sys.path[0] + '/mresult', 'r').readlines()
                    self.resultText.Clear()
                    for line in result:
                        self.resultText.write(line)
                    self.resultText.SetInsertionPoint(0)
                self.editMrButton.Enable(True)
                self.saveMrButton.Enable(True)
        self.frombutton = True

    def OnSaveMT(self, event):
        tempfile = open(sys.path[0] + '/mtresult', 'r').readlines()
        savedlg = wx.FileDialog(self, 'Save ModelTest result', os.getcwd(), style=wx.SAVE | wx.OVERWRITE_PROMPT)
        if savedlg.ShowModal() == wx.ID_OK:
            filename = savedlg.GetPath()
            savedlg.Destroy()
            file = open(filename, 'w')
            for line in tempfile:
                file.write(line)

    def OnSaveMr(self, event):
        tempfile = open(sys.path[0] + '/mresult', 'r').readlines()
        savedlg = wx.FileDialog(self, 'Save MrModelTest result', os.getcwd(), style=wx.SAVE | wx.OVERWRITE_PROMPT)
        if savedlg.ShowModal() == wx.ID_OK:
            filename = savedlg.GetPath()
            savedlg.Destroy()
            file = open(filename, 'w')
            for line in tempfile:
                file.write(line)

    def OnEditNexus(self, event):
        wx.MessageBox('Not implemented in version 1.0')
        #if self.fromMT == True:
        #    tempfile = open(sys.path[0] + '/mtresult', 'r').readlines()
        #    linenumber = self.findBlock(tempfile)
        #    print linenumber
        #    
        #    seldlg = wx.FileDialog(self, 'Select Nexus file', os.getcwd(), style=wx.OPEN)
        #    if seldlg.ShowModal() == wx.ID_OK:
        #        filename = seldlg.GetPath()
        #        seldlg.Destroy()
        #        nexusfile = open(filename, 'r').readlines()
        #        block = re.compile('\[begin paup;', re.IGNORECASE)
        #        for line in nexusfile:
        #            print block.match(line), line

    def findBlock(self, file):
        ns = []
        for i in range(len(file)):
            if file[i].find('[!') >= 0:
                ns.append(i)
            if file[i].find('END;') >= 0:
                ns.append(i)
        return ns

    def check_nexus(self, file):
        buffer = open(file, 'r').readlines()
        for line in buffer:
            if line.find('#NEXUS') >= 0:
                return 1
            else:
                return 2

def check_paths():
    currentdir = os.getcwd()
    paths = []
    try:
        mt = open(currentdir + '/.mt.ini', 'r').readline()
        paths.append(mt)
    except:
        paths.append(0)

    try:
        mr = open(currentdir + '/.mr.ini', 'r').readline()
        paths.append(mr)
    except:
        paths.append(0)

    try:
        p = open(currentdir + '/.p.ini', 'r').readline()
        paths.append(p)
    except:
        paths.append(0)
    print 'paths checked'
    print paths

    return paths

if __name__ == '__main__':
    paths = check_paths()

    app = wx.PySimpleApp()
    frame = MrMTGuiMain(parent=None, id = -1)
    frame.Show()
    app.MainLoop()












